/*
 * Copyright (c) 2025 EasyAdmin
 * All rights reserved.
 *
 * This file is part of the [EasAdmin] project.
 * Unauthorized copying of this file, via any medium, is strictly prohibited.
 * Proprietary and confidential.
 *
 * Author: EasyAdmin ( 1073602@qq.com )
 * Website: https://www.xhxiao.com
 */
package com.easy.app.controller.system;

import com.easy.framework.common.model.R;
import com.easy.framework.common.utils.ConvertUtil;
import com.easy.framework.common.validate.Add;
import com.easy.framework.database.page.Pagination;
import com.easy.framework.poi.utils.ExcelUtils;
import com.easy.framework.web.base.BaseController;
import com.easy.module.log.annotation.Log;
import com.easy.module.log.enums.Operation;
import com.easy.module.system.entity.SysRole;
import com.easy.module.system.query.SysRoleQuery;
import com.easy.module.system.service.ISysDeptService;
import com.easy.module.system.service.ISysRoleService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 角色管理 控制器
 *
 * @author EasyAdmin ( 1073602@qq.com )
 * @date 2025-08-19
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController {

    final ISysRoleService sysRoleService;

    final ISysDeptService sysDeptService;

    @PreAuthorize("@perm.hasPermission('system:role$list')")
    @GetMapping("/page")
    public R<Pagination<SysRole>> page(SysRoleQuery query) {
        return R.success(sysRoleService.page(query));
    }

    @Log(title = "角色管理", type = Operation.EXPORT)
    @PreAuthorize("@perm.hasPermission('system:role$export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysRoleQuery query) throws IOException {
        List<SysRole> list = sysRoleService.queryList(query);
        ExcelUtils.exportExcel(response, list, "角色数据");
    }

    /**
     * 根据角色编号获取详细信息
     */
    @PreAuthorize("@perm.hasPermission('system:role$query')")
    @GetMapping(value = "/{roleId}")
    public R<SysRole> get(@PathVariable("roleId") Long roleId) {
        sysRoleService.validateDataScope(roleId);
        return R.success(sysRoleService.getById(roleId));
    }

    /**
     * 新增角色
     */
    @PreAuthorize("@perm.hasPermission('system:role$add')")
    @Log(title = "角色管理", type = Operation.INSERT)
    @PostMapping
    public R add(@Validated({Add.class}) @RequestBody SysRole role) {
        if (sysRoleService.exists(SysRole::getRoleName, role.getRoleName())) {
            return R.fail("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        } else if (sysRoleService.exists(SysRole::getRoleKey, role.getRoleKey())) {
            return R.fail("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        return R.result(sysRoleService.add(role));
    }

    /**
     * 修改保存角色
     */
    @PreAuthorize("@perm.hasPermission('system:role$edit')")
    @Log(title = "角色管理", type = Operation.UPDATE)
    @PutMapping
    public R edit(@Validated @RequestBody SysRole role) {
        sysRoleService.validateDataScope(role.getId());
        if (sysRoleService.exists(SysRole::getRoleName, role.getRoleName(), SysRole::getId, role.getId())) {
            return R.fail("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        } else if (sysRoleService.exists(SysRole::getRoleKey, role.getRoleKey(), SysRole::getId, role.getId())) {
            return R.fail("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        if (sysRoleService.update(role)) {
            return R.success();
        }
        return R.fail("修改角色'" + role.getRoleName() + "'失败，请联系管理员");
    }

    /**
     * 删除角色
     */
    @PreAuthorize("@perm.hasPermission('system:role$remove')")
    @Log(title = "角色管理", type = Operation.DELETE)
    @DeleteMapping("/{roleIds}")
    public R remove(@PathVariable("roleIds") Long[] roleIds) {
        return R.result(sysRoleService.deleteByIds(roleIds));
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@perm.hasPermission('system:role$edit')")
    @Log(title = "角色管理", type = Operation.UPDATE)
    @PutMapping("/changeStatus")
    public R changeStatus(@RequestBody SysRole role) {
        sysRoleService.validateDataScope(role.getId());
        SysRole entity = new SysRole();
        entity.setId(role.getId());
        entity.setStatus(role.getStatus());
        return R.result(sysRoleService.updateById(entity));
    }

    /**
     * 修改保存数据权限
     */
    @PreAuthorize("@perm.hasPermission('system:role$edit')")
    @Log(title = "角色管理", type = Operation.UPDATE)
    @PutMapping("/dataScope")
    public R dataScope(@RequestBody SysRole role) {
        sysRoleService.validateDataScope(role.getId());
        return R.result(sysRoleService.authDataScope(role));
    }

    /**
     * 获取对应角色部门树列表
     */
    @PreAuthorize("@perm.hasPermission('system:role$query')")
    @GetMapping(value = "/deptTree/{roleId}")
    public R deptTree(@PathVariable("roleId") Long roleId) {
        Map<String, Object> data = new HashMap<>();
        data.put("checkedKeys", ConvertUtil.convert(sysRoleService.getDeptIdListByRoleId(roleId),String.class));
        data.put("depts", sysDeptService.treeList(sysDeptService.list()));
        return R.success(data);
    }
}
